package com.tvunetworks.center.user.config.datasource;

import com.tvunetworks.center.user.config.mybatis.MyMybatisProperties;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
* @ClassName: MybatisConfiguration
* @Description: sqlsession以及mybatis插件配置
* @author lebron
* 2018年4月11日
*
*/
@Configuration
@ConditionalOnClass({EnableTransactionManagement.class })
@Import({DataBaseConfiguration.class })
public class MybatisConfiguration {

@Value("${spring.datasource.type}")
private Class<? extends DataSource> dataSourceType;

@Value("${datasource.readSize}")
private String dataSourceSize;

@Autowired
@Qualifier("writeDataSource")
private DataSource dataSource;

@Autowired
@Qualifier("readDataSources")
private List<DataSource> readDataSources;

    @Autowired
    private MyMybatisProperties mybatisProperties;

    /**
     *
     * @return SqlSessionFactory
     * @throws Exception 编译异常
     */
    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        // 解决myBatis下 不能嵌套jar文件的问题
        VFS.addImplClass(SpringBootVFS.class);
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(roundRobinDataSourceProxy());
        factory.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
        factory.setMapperLocations(mapperLocations());
        SqlSessionFactory object = factory.getObject();
        if (object!=null){
            object.getConfiguration().setMapUnderscoreToCamelCase(true);
        }
        return factory.getObject();
    }

    /**
     *
     * @return Resource
     * @throws IOException 编译异常
     */
    @Bean
    public Resource[] mapperLocations() throws IOException {
        return new PathMatchingResourcePatternResolver().getResources(mybatisProperties.getMapperLocations());
    }

    /**
     * 有多少个数据源就要配置多少个bean
     * @return  AbstractRoutingDataSource
     */
    @Bean
    public AbstractRoutingDataSource roundRobinDataSourceProxy() {

        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put(DataSourceType.write.getType(), dataSource);

        int size = Integer.parseInt(dataSourceSize);
        RoutingDataSource proxy = new RoutingDataSource(size);
        for (int i = 0; i < size; i++) {
            targetDataSources.put(i, readDataSources.get(i));
        }
        proxy.setDefaultTargetDataSource(dataSource);
        proxy.setTargetDataSources(targetDataSources);
        return proxy;
    }

}
